using UnityEngine;
using System.Collections;

/**
 * Shooting behavior for ranged enemey
 */
public class RangedShoot : MonoBehaviour {
	/**
	 * Seconds between shots.
	 **/
	private const float shotDelaySecs = 0.1f;
	
	/**
	 * Seconds between burts
	 **/
	private const float burstDelaySecs = 1f;
	
	/**
	 * Max shots in a single burst.
	 **/
	private const int burstMax = 3;
	
	/**
	 * Boolean flag to control enemy firing directly at player position,
	 * or at fixed direction(s)
	 **/
	private const bool dontShootAtPlayer = true;
	
	/**
	 * Distance player must be within for a move/shoot update to occur
	 **/
	private const float xDistToActivate = 50;
		
	/*
	 * Prefab ref for enemyBullet
	 */
	public GameObject enemyBullet;
	private ArrayList bulletList = new ArrayList();
	public Animator anim;
	float animFloat=0;
	
	// offsets used for generating bullets relative to enemy's transform.position
	private const float xBulletOffset = 0;
	private const float yBulletOffset = 0;
	
	private float lastShotTime = 0;
	private float lastBurstTime = 0;
	private int burstCount = 0;
	
	//-- EnemyMovement methods --//
	// Use this for initialization
	void Start () {
		//...
	}
	
	// Update is called once per frame
	void Update () {
		// find distance
		GameObject player = GenerateObjects.getPlayer();
		if (player == null) {
			return;
		}
		
		Vector3 playerPosition = player.transform.position;
		float diff = playerPosition.x - this.transform.position.x;
		if (diff < 0)
			diff *= -1;
		if (diff > xDistToActivate) {
			// kill updates on distance units?
			return;	
		}
		
		// *** Handle shots
		float now = Time.timeSinceLevelLoad;
		
		// are we in a burst?
		if (this.lastBurstTime < 1 
			|| now - this.lastBurstTime > burstDelaySecs) {
			this.burstCount = 0;
			this.lastBurstTime = now;
			this.lastShotTime = now;
		}
		
		if (this.burstCount < burstMax ) {
			if (now - this.lastShotTime > shotDelaySecs) {
				// calculate bullet spawn
				float bX = this.transform.position.x - xBulletOffset;
				float bY = this.transform.position.y - yBulletOffset;
					
				// spawn it
				Vector3 dirToPlayer = this.transform.position - playerPosition;
				dirToPlayer.Normalize();
				
				if (dontShootAtPlayer) {
					// round to compass points
					roundVector( dirToPlayer );
				}
				createBullet( bX, bY, dirToPlayer );
				
				this.lastShotTime = now;
				this.burstCount++;
			}
			animFloat= Mathf.Lerp(animFloat, 10, Time.deltaTime*3);
			anim.SetFloat("Shoot", animFloat);
		}
		else {
			animFloat= Mathf.Lerp(animFloat, 0, Time.deltaTime*3);
			anim.SetFloat("Shoot", animFloat);
		}
	}
	
	/**
	 * Helper to round passed Vector3 to diagonals or directionals.
	 **/
	private void roundVector( Vector3 dirToPlayer ) {
		// y mangle
		if (dirToPlayer.y < 0.5f) {
			if (dirToPlayer.y < 0.25f) {
				dirToPlayer.y = 0f;	
			}
			else {
				dirToPlayer.y = 0.5f;
			}
		}
		else {
			if (dirToPlayer.y > 0.75f) {
				dirToPlayer.y = 1.0f;	
			}
			else {
				dirToPlayer.y = 0.5f;
			}
		}
		
		// x mangle
		if (dirToPlayer.x < 0.5f) {
			if (dirToPlayer.x < 0.25f) {
				dirToPlayer.x = 0f;	
			}
			else {
				dirToPlayer.x = 0.5f;
			}
		}
		else {
			if (dirToPlayer.x > 0.75f) {
				dirToPlayer.x = 1.0f;	
			}
			else {
				dirToPlayer.x = 0.5f;
			}
		}
		
		// renormalize since this is lazy?
		dirToPlayer.Normalize();
	}
	
	/**
	 * Creates new EnemyBullet positioned at passed x,y.
	 * Passed direction should be a normalized Vector3 to travel in
	 * @param x - X coord for bullet spawn
	 * @param y - Y coord for bullet spawn
	 * @param direction - Normalized Vector3 to fire in direction of
	 **/
	public void createBullet( float x, float y, Vector3 direction ) {
		GameObject result = (GameObject) Instantiate( enemyBullet, new Vector3(x, y, 0), Quaternion.identity );
		result.GetComponent<BulletMovement>().direction = direction;
		result.GetComponent<BulletMovement>().source = new Vector3(x,y,0);
		
		this.bulletList.Add( result );
	}
	
	/**
	 * Cleans up any bullets
	 **/
	public void clearBullets() {
		foreach (GameObject killMe in this.bulletList) {
			Destroy( killMe );
		}
		this.bulletList.Clear();
	}
}
